#include "bsp_uart.h"

#define BSP_UART_LOG "[bsp_uart]"

#define BSP_UART_DEBUG_LOG_OPEN // 开启调试信息

/**
 * @brief  初始化串口通信设备。
 * @param  [in] uart_bus 需要初始化的UART设备， 参考 @ref uart_bus_t 。
 * @param  [in] baudrate 串口波特率。
 * @param  [in] uart_buffer_config 串口缓冲区配置结构体指针，参考 @ref uart_buffer_config_t 。
 * @retval ERRCODE_SUCC 成功。
 * @retval Other        失败，参考 @ref errcode_t 。
 */
errcode_t bsp_uart_init(uart_bus_t uart_bus, uint32_t baudrate, uart_buffer_config_t *uart_buffer_config)
{
    errcode_t ret;

    // 检查参数
    if (uart_bus >= UART_BUS_NONE || baudrate == 0 || uart_buffer_config == NULL)
    {
#ifdef BSP_UART_DEBUG_LOG_OPEN
        osal_printk("%s parameter error.\n", BSP_UART_LOG);
#endif
        return ERRCODE_INVALID_PARAM;
    }

    // 初始化串口设备
    uart_attr_t attr = {
        .baud_rate = baudrate,
        .data_bits = UART_DATA_BIT_8, // 8位数据位
        .stop_bits = UART_STOP_BIT_1, // 1位停止位
        .parity = UART_PARITY_NONE};  // 无校验位
    uart_pin_config_t pin_config = {
        .cts_pin = PIN_NONE,
        .rts_pin = PIN_NONE};

    // 初始化串口IO引脚
    if (uart_bus == UART_BUS_0)
    {
        // 初始化串口IO
        uapi_pin_set_mode(GPIO_17, PIN_MODE_1);
        uapi_pin_set_mode(GPIO_18, PIN_MODE_1);

        pin_config.rx_pin = GPIO_18;
        pin_config.tx_pin = GPIO_17;
    }
    else if (uart_bus == UART_BUS_1)
    {
        // 初始化串口IO
        uapi_pin_set_mode(GPIO_15, PIN_MODE_1);
        uapi_pin_set_mode(GPIO_16, PIN_MODE_1);

        pin_config.rx_pin = GPIO_16;
        pin_config.tx_pin = GPIO_15;
    }
    else if (uart_bus == UART_BUS_2)
    {
        // 初始化串口IO
        uapi_pin_set_mode(GPIO_07, PIN_MODE_2);
        uapi_pin_set_mode(GPIO_08, PIN_MODE_2);

        pin_config.rx_pin = GPIO_07;
        pin_config.tx_pin = GPIO_08;
    }

    // 初始化串口设备
    uapi_uart_deinit(uart_bus);
    ret = uapi_uart_init(uart_bus, &pin_config, &attr, NULL, uart_buffer_config);
    if (ret != ERRCODE_SUCC)
    {
#ifdef BSP_UART_DEBUG_LOG_OPEN
        osal_printk("%s uart%d init failed.\n", BSP_UART_LOG, uart_bus);
#endif
        return ret;
    }

    return ERRCODE_SUCC;
}

/**
 * @brief  通过串口发送数据。
 * @param  [in] uart_bus 串口总线，参考 @ref uart_bus_t 。
 * @param  [in] buf      要发送的数据缓冲区。
 * @param  [in] len      要发送的数据长度。
 * @retval 成功发送的数据字节数 成功。
 * @retval 0 失败。
 */
uint32_t bsp_uart_send_data(uart_bus_t uart_bus, const uint8_t *buf, uint32_t len)
{
    // 参数检查
    if (uart_bus >= UART_BUS_NONE || buf == NULL || len == 0)
    {
#ifdef BSP_UART_DEBUG_LOG_OPEN
        osal_printk("%s parameter error.\n", BSP_UART_LOG);
#endif
        return ERRCODE_INVALID_PARAM;
    }

    // 发送数据
    uint32_t ret = uapi_uart_write(uart_bus, buf, len, 0);
    if (ret == 0)
    {
#ifdef BSP_UART_DEBUG_LOG_OPEN
        osal_printk("%s uart%d send data failed.\n", BSP_UART_LOG, uart_bus);
#endif

        return 0;
    }

    return ret;
}

/**
 * @brief  注册串口接收处理函数。
 * @param  [in] uart_bus 串口总线，参考 @ref uart_bus_t 。
 * @param  [in] callback 接收处理函数，参考 @ref uart_rx_callback_t 。
 * @retval ERRCODE_SUCC 成功。
 * @retval Other        失败，参考 @ref errcode_t 。
 */
errcode_t bsp_uart_register_rx(uart_bus_t uart_bus, uart_rx_callback_t callback)
{
    // 参数检查
    if (uart_bus >= UART_BUS_NONE || callback == NULL)
    {
#ifdef BSP_UART_DEBUG_LOG_OPEN
        osal_printk("%s parameter error.\n", BSP_UART_LOG);
#endif
        return ERRCODE_INVALID_PARAM;
    }

    // 注销串口接收处理函数，防止重复注册。
    uapi_uart_unregister_rx_callback(uart_bus);

    // 注册串口接收处理函数。
    errcode_t ret = uapi_uart_register_rx_callback(uart_bus, UART_RX_CONDITION_FULL_OR_IDLE, 1, callback);
    if (ret != ERRCODE_SUCC)
    {
#ifdef BSP_UART_DEBUG_LOG_OPEN
        osal_printk("%s uart%d register rx failed.\n", BSP_UART_LOG, uart_bus);
#endif
        return ret;
    }

    return ERRCODE_SUCC;
}
